const express = require('express');
const app = express();
const {createServer: createViteServer} = require('vite');
const fs = require('fs');

/** dev*/
/*createViteServer({
  server: {
    middlewareMode: 'ssr'
  }
})
  .then(vite => {
    app.use(vite.middlewares);

    app.get('*', async (req,res) => {
      let template = fs.readFileSync('index.html','utf-8');

      template = await vite.transformIndexHtml(req.url,template)
      //↑ 会引入 <script type="module" src="/@vite/client"></script>
      //并且加入下面这么一坨用于 react 热更新的代码
      /!*
        <script type="module">
          import RefreshRuntime from "/@react-refresh"
          RefreshRuntime.injectIntoGlobalHook(window)
          window.$RefreshReg$ = () => {}
          window.$RefreshSig$ = () => (type) => type
          window.__vite_plugin_react_preamble_installed__ = true
        </script>
      *!/

      const {render} = await vite.ssrLoadModule('/src/server-entry.jsx'); //我们的项目里用的是es6module 故要在这里的nodejs项目的server里正确加载依赖, 需要利用到 vite.ssrLoadModule (但生产模式下不用 )
      const html = await render(req.url);
      const responseHtml = template.replace('<!--APP_HTML-->', html);
      res
        .set('content-type', 'text/html')
        .send(responseHtml);
    });

    app.listen(4000);
  });*/



/** prod*/
//相较开发环境的优化:
//1. 开发环境下不会再每次重新读取模板文件 直接使用打包好的即可
//2. 不再需要注入vite的客户端代码(因为不再需要热更新撒的了)
const template = fs.readFileSync('dist/client/index.html', 'utf-8');
//将静态资源请求映射到client部分打包出来的目录
app.use(express.static('dist/client'));
app.get('*',async (req, res) => {
  //仍然需要使用server-entry帮我们做服务端的渲染
  //然后替换掉打包好后的模板文件中的占位符
  const render = require('./dist/server/server-entry').render;

  //记录我们服务端渲染时想要传递出来的信息
  const context = {};
  // if(context.xxx) //todo something
  //比如 我们服务端渲染了一个路由 但是这个渲染出的路由结果又会跳转到另外一个路由
  //其实我们就没必要将渲染出的第一次结果返回给客户端 让客户端再请求服务端进行跳转
  //而是可以直接在服务端就进行跳转 然后把最终渲染的路由结果返回给客户单
  /*if(context.url){
    return res.redirect(301,context.url)
  }*/
  const html = await render(req.url, context);

  const responseHtml = template.replace('<!--APP_HTML-->', html);
  res
    .set('content-type', 'text/html')
    .send(responseHtml);
});
app.listen(4000);


//todo const isProd = process.env.NODE_ENV === 'production'
